<script lang="ts" setup>
import '@wangeditor/editor/dist/css/style.css'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IDomEditor } from '@wangeditor/editor'
import { useFormDisabled, useFormItem } from 'element-plus'
import to from 'await-to-js'
import { toolbarConfig } from './data'
import { getTokenHeader } from '@/utils/auth'

type InsertFnType = (url: string, alt?: string, href?: string) => void

withDefaults(
  defineProps<{
    disabled?: boolean
  }>(),
  {
    disabled: false
  }
)
const isDisabled = useFormDisabled()
const { formItem } = useFormItem()

const mode = ref('default')
const editorRef = ref()
const modelValue = defineModel<string>({ required: true })
const value = ref(modelValue.value)

watch(
  () => modelValue.value,
  (val) => {
    value.value = val
  }
)

watch(
  () => value.value,
  (val) => {
    if (val?.toString() === '<p><br></p>') {
      modelValue.value = undefined
      return
    }
    modelValue.value = val
  }
)

const editorConfig = computed(() => {
  const readOnly = isDisabled.value
  return {
    readOnly,
    MENU_CONF: {
      uploadImage: {
        async customUpload(response: File, insertFn: InsertFnType) {
          const [err, res] = await to(uploadFlie(response))

          if (err) return
          const { url } = res.object
          insertFn(url)
        }
      },
      uploadVideo: {
        async customUpload(response: File, insertFn: InsertFnType) {
          const [err, res] = await to(uploadFlie(response))
          if (err) return
          const { url } = res.object
          insertFn(url)
        }
      },
      fontSize: {
        fontSizeList: ['12px', '14px', '16px', '18px', '20px', '22px', '24px', '26px', '28px']
      }
    }
  }
})

const handleCreated = (editor: string) => {
  editorRef.value = editor
}
const handleChange = () => {
  formItem?.validate('change').catch(() => {})
}

async function uploadFlie(file: File) {
  const formData = new FormData()
  formData.append('file', file)
  return await fetch(import.meta.env.VITE_APP_UPLOAD_URL, {
    method: 'POST',
    body: formData,
    headers: getTokenHeader()
  })
    .then((res) => res.json())
    .then((res) => {
      if (res.retCode !== '000000') {
        const msg = res.retMsg || '上传失败'
        this.$message.error(msg)
        throw new Error(msg)
      }
      return res
    })
}
</script>

<template>
  <div class="w-full el-border">
    <Toolbar style="border-bottom: var(--el-border)" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
    <Editor
      style="height: 500px; overflow-y: hidden"
      v-model="value"
      :defaultConfig="editorConfig"
      :mode="mode"
      v-on="$attrs"
      @onCreated="handleCreated"
      @onChange="handleChange" />
  </div>
</template>
